package com.zhanghe.springsecurity.filter;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.zhanghe.springsecurity.Service.TokenService;
import com.zhanghe.springsecurity.configuration.ApplicationConfig;
import com.zhanghe.springsecurity.jwt.JwtUtil;
import com.zhanghe.springsecurity.util.ReturnValue;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.GenericFilterBean;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * AuthenticationFilter
 *
 * @author Clevo
 * @date 2018/3/25
 */
public class AuthenticationFilter extends OncePerRequestFilter {

    private  static  final Logger logger = LoggerFactory.getLogger(AuthenticationFilter.class);

    @Autowired
    private ApplicationConfig applicationConfig;

    @Autowired
    private TokenService tokenService;

    @Override
    public void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws IOException, ServletException {
        logger.debug("进入token验证过滤器");
        String jwtoken = httpServletRequest.getHeader("Authorization");
        ArrayList<GrantedAuthority> authorities = new ArrayList<>();
        Gson gson = new Gson();
        String sub = "";
        StringBuffer roles = new StringBuffer();
        httpServletResponse.setContentType("application/json");
        httpServletResponse.setStatus(HttpServletResponse.SC_OK);
        String originHeader = httpServletRequest.getHeader("Origin");
        String[] IPs = applicationConfig.getOrigins().split(",");
        if (Arrays.asList(IPs).contains(originHeader)) {
            httpServletResponse.setHeader("Access-Control-Allow-Origin", originHeader);
            httpServletResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
            httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
            httpServletResponse.setHeader("Access-Control-Allow-Headers", "authorization,Content-Type");
        }
        try{
            if(jwtoken!=null){
                String rolestr = tokenService.getValueFromToken(jwtoken, "roles").toString();
                for(String role: (List<String>)gson.fromJson(rolestr, List.class)){
                    authorities.add( new SimpleGrantedAuthority(role) );
                    roles.append(role).append(",");
                }
                sub = tokenService.getValueFromToken(jwtoken, "sub").toString();
                logger.debug("token记录权限:"+roles.toString());
                SecurityContextHolder.getContext()
                        .setAuthentication(new UsernamePasswordAuthenticationToken(sub, null, authorities));

            }else{
                SecurityContextHolder.getContext()
                        .setAuthentication(new UsernamePasswordAuthenticationToken(null, null, null));
                //logger.debug("用户 未登录");
                //httpServletResponse.getOutputStream().write(new ReturnValue<>(ReturnCode.UNLOGIN, "用户 未登录").toJson().getBytes());
                //return;
            }
        }catch(ExpiredJwtException e){
            logger.debug("用户 令牌过期 过期令牌:"+jwtoken);
            httpServletResponse.getOutputStream().write(new ReturnValue<>(-1, "用户 令牌过期").toString().getBytes());
            return;
        }catch (Exception e) {
            logger.debug("用户 令牌不合法:"+jwtoken);
            logger.debug("用户 令牌不合法 exception:"+e.getMessage());
            httpServletResponse.getOutputStream().write(new ReturnValue<>(-2, "用户 令牌不合法").toString().getBytes());
            return;
        }
        filterChain.doFilter(httpServletRequest,httpServletResponse);
    }
}
